<template>
  <el-dialog
    :model-value="visible"
    class="requirement-detail-dialog"
    width="1400px"
    align-center
    :close-on-click-modal="false"
    :before-close="handleClose"
    @update:model-value="(value: boolean) => emit('update:visible', value)"
  >
    <div class="requirement-detail">
        <div class="detail-body">
        <div class="primary-column">
          <div class="detail-header">
            <div class="header-top">
              <span v-if="localRequirement.id" class="detail-id">ID {{ localRequirement.id }}</span>
              <div class="status-tags">
                <el-tag
                  v-if="localRequirement.status"
                  :type="getStatusTypeWrapper(localRequirement.status)"
                  size="small"
                >
                  {{ getStatusTextWrapper(localRequirement.status) }}
                </el-tag>
                <el-tag
                  v-if="localRequirement.priority"
                  :type="getPriorityTypeWrapper(localRequirement.priority)"
                  size="small"
                >
                  {{ getPriorityTextWrapper(localRequirement.priority) }}
                </el-tag>
                <el-tag v-if="localRequirement.requirement_type" size="small" type="info">
                  {{ getTypeTextWrapper(localRequirement.requirement_type) }}
                </el-tag>
              </div>
            </div>

            <div class="title-section" ref="titleFieldRef">
              <div class="field-label">
                <span>需求标题</span>
                <span class="required">*</span>
              </div>
              <el-input
                v-model="drafts.title"
                placeholder="请输入需求标题"
                maxlength="200"
                show-word-limit
                size="large"
                class="title-input"
                :class="{ 'field-error': fieldErrors.title }"
                @blur="saveTitle"
                @input="clearFieldErrorWrapper('title')"
              />
              <div v-if="fieldErrors.title" class="error-message">{{ fieldErrors.title }}</div>
            </div>

            <div class="header-meta">
              <span v-if="localRequirement.parent_id && localRequirement.parent_name" class="parent-info">
                <el-icon><ArrowLeft /></el-icon>
                父需求：<el-link type="primary" @click="handleViewParent(localRequirement.parent_id)" :underline="false">{{ localRequirement.parent_name }}</el-link>
              </span>
              <span>创建人：<UserDisplay :user-id="localRequirement.reporter_id" :user-name="localRequirement.reporter_name" :show-avatar="false" size="small" /></span>
              <span>负责人：<UserDisplay :user-id="localRequirement.assignee_id" :user-name="localRequirement.assignee_name" :show-avatar="false" size="small" /></span>
              <span v-if="localRequirement.created_at">创建时间：{{ formatDateTimeDisplay(localRequirement.created_at) }}</span>
              <span v-if="localRequirement.updated_at">更新时间：{{ formatDateTimeDisplay(localRequirement.updated_at) }}</span>
            </div>
          </div>
          <!-- 第一组页签：需求描述、验收标准、商业价值 -->
          <section class="section-card tabs-card">
            <el-tabs v-model="contentTab" class="content-tabs">
              <el-tab-pane label="需求描述" name="description">
                <div class="tab-content-wrapper">
                  <div class="section-header">
                    <span class="section-title">需求描述</span>
                    <div class="section-actions">
                      <template v-if="!editingDescription">
                        <el-button
                          size="small"
                          type="primary"
                          @click="startEditDescription"
                        >
                          编辑
                        </el-button>
                      </template>
                      <template v-else>
                        <el-button
                          size="small"
                          @click="cancelEditDescription"
                        >
                          取消
                        </el-button>
                        <el-button
                          size="small"
                          type="primary"
                          :loading="saving.description"
                          :disabled="!canSaveDescription"
                          @click="saveDescription"
                        >
                          保存
                        </el-button>
                      </template>
                    </div>
                  </div>
                  <div class="section-content">
                    <EnhancedRichTextEditor
                      v-if="editingDescription"
                      v-model="drafts.description"
                      placeholder="请描述需求内容..."
                      :min-height="400"
                    />
                    <div v-else class="rich-text-content" v-html="localRequirement.description || '暂无描述'"></div>
                  </div>
                </div>
              </el-tab-pane>

              <el-tab-pane label="验收标准" name="acceptance">
                <div class="tab-content-wrapper">
                  <div class="section-header">
                    <span class="section-title">验收标准</span>
                    <div class="section-actions">
                      <template v-if="!editingAcceptance">
                        <el-button
                          size="small"
                          type="primary"
                          @click="startEditAcceptance"
                        >
                          编辑
                        </el-button>
                      </template>
                      <template v-else>
                        <el-button
                          size="small"
                          @click="cancelEditAcceptance"
                        >
                          取消
                        </el-button>
                        <el-button
                          size="small"
                          type="primary"
                          :loading="saving.acceptance"
                          :disabled="!canSaveAcceptance"
                          @click="saveAcceptance"
                        >
                          保存
                        </el-button>
                      </template>
                    </div>
                  </div>
                  <div class="section-content">
                    <el-input
                      v-if="editingAcceptance"
                      v-model="drafts.acceptance_criteria"
                      type="textarea"
                      placeholder="请填写验收标准"
                      :rows="6"
                      maxlength="2000"
                      show-word-limit
                      resize="vertical"
                    />
                    <div v-else class="text-content">{{ localRequirement.acceptance_criteria || '暂无验收标准' }}</div>
                  </div>
                </div>
              </el-tab-pane>

              <el-tab-pane label="商业价值" name="business">
                <div class="tab-content-wrapper">
                  <div class="section-header">
                    <span class="section-title">商业价值</span>
                    <div class="section-actions">
                      <template v-if="!editingBusiness">
                        <el-button
                          size="small"
                          type="primary"
                          @click="startEditBusiness"
                        >
                          编辑
                        </el-button>
                      </template>
                      <template v-else>
                        <el-button
                          size="small"
                          @click="cancelEditBusiness"
                        >
                          取消
                        </el-button>
                        <el-button
                          size="small"
                          type="primary"
                          :loading="saving.business"
                          :disabled="!canSaveBusiness"
                          @click="saveBusiness"
                        >
                          保存
                        </el-button>
                      </template>
                    </div>
                  </div>
                  <div class="section-content">
                    <el-input
                      v-if="editingBusiness"
                      v-model="drafts.business_value"
                      type="textarea"
                      placeholder="请描述该需求的商业价值（可选）"
                      :rows="5"
                      maxlength="1000"
                      show-word-limit
                      resize="vertical"
                    />
                    <div v-else class="text-content">{{ localRequirement.business_value || '暂无商业价值描述' }}</div>
                  </div>
                </div>
              </el-tab-pane>
            </el-tabs>
          </section>

          <!-- 第二组页签：动态、评论、附件、关联项、其他 -->
          <section class="section-card tabs-card">
            <el-tabs v-model="activeTab" class="detail-tabs">
              <el-tab-pane label="动态" name="activities">
                <div class="tab-content">
                  <ActivityList
                    entity-type="requirement"
                    :entity-id="localRequirement.id"
                    :requirement="localRequirement"
                    :status-options="statusOptions"
                    :priority-options="priorityOptions"
                    :users="users"
                  />
                </div>
              </el-tab-pane>
              
              <el-tab-pane label="评论" name="comments">
                <div class="tab-content">
                  <CommentList
                    entity-type="requirement"
                    :entity-id="localRequirement.id"
                    @comment-count-change="handleCommentCountChange"
                  />
                </div>
              </el-tab-pane>
              
              <el-tab-pane label="附件" name="attachments">
                <div class="tab-content">
                  <AttachmentManager
                    :attachments="localRequirement.attachments || []"
                    :upload-handler="handleUploadAttachment"
                    :delete-handler="handleDeleteAttachmentWrapper"
                    :download-handler="handleDownloadAttachmentWrapper"
                    :can-delete="true"
                    @upload-success="handleAttachmentMutation"
                    @delete-success="handleAttachmentMutation"
                  />
                </div>
              </el-tab-pane>
              
              <el-tab-pane label="子项" name="children">
                <div class="tab-content">
                  <RequirementChildrenTab
                    :requirement-id="localRequirement.id"
                    :project-id="localRequirement.project_id"
                    :status-options="statusOptions"
                    :priority-options="priorityOptions"
                    @create-child="handleCreateChild"
                    @view-child="handleViewChild"
                    @child-updated="handleChildUpdated"
                  />
                </div>
              </el-tab-pane>
              
              <el-tab-pane label="关联项" name="associations">
                <div class="tab-content">
                  <RequirementAssociationsTab
                    ref="associationsTabRef"
                    :requirement-id="localRequirement.id"
                    :version-ids="localRequirement.versions?.map(v => v.id) || []"
                    :project-id="localRequirement.project_id"
                    @task-updated="handleRelatedTaskUpdated"
                    @defect-updated="handleRelatedDefectUpdated"
                    @create-task="handleCreateTask"
                    @update-requirement="handleUpdateRequirementFromAssociation"
                  />
                </div>
              </el-tab-pane>
              
              <el-tab-pane label="其他" name="others">
                <div class="tab-content">
                  <div class="other-info">
                    <div class="other-section">
                      <div class="other-title">时间信息</div>
                      <div class="other-row">
                        <span class="other-label">创建时间</span>
                        <span class="other-value">{{ formatDateTimeDisplay(localRequirement.created_at) }}</span>
                      </div>
                      <div class="other-row">
                        <span class="other-label">更新时间</span>
                        <span class="other-value">{{ formatDateTimeDisplay(localRequirement.updated_at) }}</span>
                      </div>
                      <div class="other-row" v-if="localRequirement.approved_at">
                        <span class="other-label">批准时间</span>
                        <span class="other-value">{{ formatDateTimeDisplay(localRequirement.approved_at) }}</span>
                      </div>
                      <div class="other-row" v-if="localRequirement.implemented_at">
                        <span class="other-label">实施时间</span>
                        <span class="other-value">{{ formatDateTimeDisplay(localRequirement.implemented_at) }}</span>
                      </div>
                    </div>
                    
                    <div class="other-section" v-if="hasEffort">
                      <div class="other-title">工时信息</div>
                      <div class="other-row">
                        <span class="other-label">预估工时</span>
                        <span class="other-value">{{ formatEffort(localRequirement.estimated_effort) }}</span>
                      </div>
                      <div class="other-row">
                        <span class="other-label">实际工时</span>
                        <span class="other-value">{{ formatEffort(localRequirement.actual_effort) }}</span>
                      </div>
                      <div class="other-row" v-if="localRequirement.progress !== undefined && localRequirement.progress !== null">
                        <span class="other-label">进度</span>
                        <span class="other-value">
                          <el-progress 
                            :percentage="localRequirement.progress || 0" 
                            :stroke-width="6"
                            :show-text="true"
                            :format="() => `${localRequirement.progress || 0}%`"
                            style="width: 120px;"
                          />
                        </span>
                      </div>
                      <div class="other-row" v-if="localRequirement.start_date">
                        <span class="other-label">开始日期</span>
                        <span class="other-value" style="white-space: nowrap;">{{ formatDateTimeDisplay(localRequirement.start_date) }}</span>
                      </div>
                      <div class="other-row" v-if="localRequirement.due_date">
                        <span class="other-label">截止日期</span>
                        <span class="other-value" style="white-space: nowrap;">{{ formatDateTimeDisplay(localRequirement.due_date) }}</span>
                      </div>
                    </div>
                    
                    <div class="other-section" v-if="hasAssociations">
                      <div class="other-title">关联信息</div>
                      <div v-if="localRequirement.versions?.length" class="association-section">
                        <div class="association-title">关联版本</div>
                        <div class="tag-list">
                          <el-tag
                            v-for="version in localRequirement.versions"
                            :key="version.id"
                            type="info"
                            size="small"
                            class="tag-item"
                          >
                            {{ getVersionDisplayLabel(version) }}
                          </el-tag>
                        </div>
                      </div>
                      <div v-if="localRequirement.dependencies?.length" class="association-section">
                        <div class="association-title">关联需求</div>
                        <el-timeline>
                          <el-timeline-item
                            v-for="dependency in localRequirement.dependencies"
                            :key="dependency.requirement_id"
                            type="primary"
                            size="large"
                          >
                            <div class="dependency-item">
                              <span class="dependency-title">需求ID：{{ dependency.requirement_id }}</span>
                              <span class="dependency-type">{{ getDependencyText(dependency.dependency_type) }}</span>
                              <p v-if="dependency.description" class="dependency-desc">{{ dependency.description }}</p>
                            </div>
                          </el-timeline-item>
                        </el-timeline>
                      </div>
                    </div>
                    
                    <div class="other-section" v-if="hasWatchers">
                      <div class="other-title">关注者</div>
                      <div class="tag-list">
                        <el-tag
                          v-for="watcher in localRequirement.watchers"
                          :key="watcher"
                          size="small"
                          class="tag-item"
                        >
                          {{ watcher }}
                        </el-tag>
                      </div>
                    </div>
                  </div>
                </div>
              </el-tab-pane>
            </el-tabs>
          </section>
        </div>

        <aside class="side-column">
          <section class="info-card">
            <div class="info-card-title">基础字段</div>
            <div class="info-form-group" ref="statusFieldRef">
              <label class="info-label">状态 <span class="required">*</span></label>
              <el-select
                :model-value="localRequirement.status"
                placeholder="请选择状态"
                size="default"
                :class="{ 'field-error': fieldErrors.status }"
                @update:model-value="(value: string) => updateSimpleField('status', value)"
                @change="clearFieldErrorWrapper('status')"
              >
                <el-option
                  v-for="option in statusOptions"
                  :key="option.value"
                  :value="option.value"
                  :label="option.label"
                />
              </el-select>
              <div v-if="fieldErrors.status" class="error-message">{{ fieldErrors.status }}</div>
            </div>
            <div class="info-form-group">
              <label class="info-label">优先级</label>
              <el-select
                :model-value="localRequirement.priority"
                placeholder="请选择优先级"
                size="default"
                @update:model-value="(value: string) => updateSimpleField('priority', value)"
              >
                <el-option
                  v-for="option in priorityOptions"
                  :key="option.value"
                  :label="option.label"
                  :value="option.value"
                />
              </el-select>
            </div>
            <div class="info-form-group">
              <label class="info-label">需求类型</label>
              <el-select
                :model-value="localRequirement.requirement_type"
                placeholder="请选择类型"
                size="default"
                @update:model-value="(value: string) => updateSimpleField('requirement_type', value)"
              >
                <el-option
                  v-for="option in typeOptions"
                  :key="option.value"
                  :value="option.value"
                  :label="option.label"
                />
              </el-select>
            </div>
            <div class="info-form-group">
              <label class="info-label">需求来源</label>
              <el-select
                :model-value="localRequirement.source"
                placeholder="请选择来源"
                size="default"
                @update:model-value="(value: string) => updateSimpleField('source', value)"
              >
                <el-option
                  v-for="option in sourceOptions"
                  :key="option.value"
                  :value="option.value"
                  :label="option.label"
                />
              </el-select>
            </div>
            <div class="info-form-group" ref="projectIdFieldRef">
              <label class="info-label">所属项目 <span class="required">*</span></label>
              <el-select
                :model-value="localRequirement.project_id"
                placeholder="请选择项目"
                filterable
                size="default"
                :class="{ 'field-error': fieldErrors.project_id }"
                @update:model-value="(value: string) => updateSimpleField('project_id', value)"
                @change="clearFieldErrorWrapper('project_id')"
              >
                <el-option
                  v-for="project in projects"
                  :key="project.id"
                  :label="project.name"
                  :value="project.id"
                />
              </el-select>
              <div v-if="fieldErrors.project_id" class="error-message">{{ fieldErrors.project_id }}</div>
            </div>
            <div class="info-form-group">
              <label class="info-label">关联版本</label>
              <el-select
                v-model="versionSelection"
                multiple
                filterable
                collapse-tags
                collapse-tags-tooltip
                placeholder="请先选择项目"
                :disabled="!localRequirement.project_id"
                :loading="versionsUpdating"
                @visible-change="handleVersionSelectVisibleChange"
              >
                <el-option
                  v-for="version in availableVersionOptions"
                  :key="version.id"
                  :label="getVersionOptionLabel(version)"
                  :value="version.id"
                />
              </el-select>
            </div>
            <div class="info-form-group">
              <label class="info-label">需求标签</label>
              <el-select
                :model-value="localRequirement.tags || []"
                multiple
                filterable
                allow-create
                default-first-option
                collapse-tags
                collapse-tags-tooltip
                placeholder="请选择标签或输入新标签"
                size="default"
                @update:model-value="(value: string[]) => updateSimpleField('tags', value)"
              >
                <el-option
                  v-for="tag in commonTagOptions"
                  :key="tag"
                  :label="tag"
                  :value="tag"
                />
              </el-select>
            </div>
          </section>

          <section class="info-card">
            <div class="info-card-title">人员</div>
            <div class="info-form-group" ref="reporterIdFieldRef">
              <label class="info-label">报告人 <span class="required">*</span></label>
              <el-select
                :model-value="localRequirement.reporter_id"
                placeholder="请先选择项目"
                filterable
                clearable
                size="default"
                :disabled="!localRequirement.project_id"
                :class="{ 'field-error': fieldErrors.reporter_id }"
                @update:model-value="(value: string | null) => updateSimpleField('reporter_id', value ?? '')"
                @change="clearFieldErrorWrapper('reporter_id')"
              >
                <el-option
                  v-for="user in availableUsers"
                  :key="user.id"
                  :label="user.name || user.username"
                  :value="user.id"
                >
                  <UserDisplay
                    :user="user"
                    :show-avatar="true"
                    size="small"
                  />
                </el-option>
              </el-select>
              <div v-if="fieldErrors.reporter_id" class="error-message">{{ fieldErrors.reporter_id }}</div>
            </div>
            <div class="info-form-group">
              <label class="info-label">负责人</label>
              <el-select
                :model-value="localRequirement.assignee_id"
                placeholder="请先选择项目"
                filterable
                clearable
                size="default"
                :disabled="!localRequirement.project_id"
                @update:model-value="(value: string | null) => updateSimpleField('assignee_id', value ?? '')"
              >
                <el-option
                  v-for="user in availableUsers"
                  :key="user.id"
                  :label="user.name || user.username"
                  :value="user.id"
                >
                  <UserDisplay
                    :user="user"
                    :show-avatar="true"
                    size="small"
                  />
                </el-option>
              </el-select>
            </div>
          </section>

          <section class="info-card">
            <div class="info-card-title">时间与工时</div>
            <div class="info-form-group">
              <label class="info-label">计划开始时间</label>
              <el-date-picker
                :model-value="localRequirement.start_date"
                type="datetime"
                value-format="YYYY-MM-DDTHH:mm:ss"
                format="YYYY-MM-DD HH:mm:ss"
                placeholder="请选择开始日期时间"
                size="default"
                style="width: 100%"
                @update:model-value="(value: string | null) => updateSimpleField('start_date', value || null)"
              />
            </div>
            <div class="info-form-group">
              <label class="info-label">计划完成时间</label>
              <el-date-picker
                :model-value="localRequirement.due_date"
                type="datetime"
                value-format="YYYY-MM-DDTHH:mm:ss"
                format="YYYY-MM-DD HH:mm:ss"
                placeholder="请选择截止日期时间"
                size="default"
                style="width: 100%"
                @update:model-value="(value: string | null) => updateSimpleField('due_date', value || null)"
              />
            </div>
            <div class="info-form-group">
              <label class="info-label">预估工时（人天）</label>
              <el-input-number
                :model-value="localRequirement.estimated_effort"
                :min="0"
                :step="0.5"
                :precision="1"
                size="default"
                style="width: 100%"
                controls-position="right"
                @update:model-value="(value: number | undefined) => updateSimpleField('estimated_effort', value ?? null)"
              />
            </div>
            <div class="info-form-group">
              <label class="info-label">进度</label>
              <div style="display: flex; align-items: center; gap: 12px;">
                <el-progress 
                  :percentage="localRequirement.progress || 0" 
                  :stroke-width="8"
                  :show-text="true"
                  :format="() => `${localRequirement.progress || 0}%`"
                  style="flex: 1;"
                />
              </div>
            </div>
          </section>

          <section class="info-card" v-if="localRequirement.versions?.length">
            <div class="info-card-title">关联版本</div>
            <div class="tag-list">
              <el-tag
                v-for="version in localRequirement.versions"
                :key="version.id"
                size="small"
                type="info"
              >
                {{ getVersionDisplayLabel(version) }}
              </el-tag>
            </div>
          </section>
        </aside>
      </div>
    </div>

    <template #footer>
      <div v-if="localRequirement.id" class="dialog-footer">
        <el-button type="danger" :loading="deleting" @click="handleDeleteClick">删除</el-button>
        <el-button @click="handleClose">关闭</el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 任务创建对话框 -->
  <TaskCreateDialog
    v-model="createTaskDialogVisible"
    :project-id="localRequirement.project_id || ''"
    :default-requirement-id="localRequirement.id || ''"
    :default-version-ids="localRequirement.versions?.map(v => v.id) || []"
    @success="handleTaskCreated"
  />
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'

import CommentList from '@/components/common/CommentList.vue'
import ActivityList from '@/components/common/ActivityList.vue'
import AttachmentManager from '@/components/common/AttachmentManager.vue'
import RequirementAssociationsTab from './RequirementAssociationsTab.vue'
import RequirementChildrenTab from './RequirementChildrenTab.vue'
import TaskCreateDialog from '@/components/task/TaskCreateDialog.vue'
import UserDisplay from '@/components/ui/UserDisplay.vue'
import { formatDateTime } from '@/utils/date'
import {
  updateRequirement,
  getRequirementById,
  uploadRequirementAttachment,
  deleteRequirementAttachment,
  deleteRequirement,
  RequirementPriority,
  RequirementSource,
  RequirementType,
  type RequirementAttachment,
  type RequirementResponse,
  type RequirementUpdate
} from '@/api/requirements'
import { useRequirementOptions } from '@/composables/useRequirementOptions'
import { ResponseParser } from '@/utils/responseParser'
import { versionAPI, RelationType } from '@/api/version'
import { useRequirementStates } from '@/composables/useRequirementStates'
import {
  type StatusOption,
  type BasicOption,
  type ProjectOption,
  type VersionOption,
  getStatusType,
  getStatusText,
  getPriorityType,
  getPriorityText,
  getTypeText,
  getVersionOptionLabel,
  clearFieldError,
  validateRequiredField
} from '../utils/requirementUtils'
import type { User } from '@/types/user'
import { useRequirementsStore } from '@/stores/requirements'

interface LocalRequirement {
  id: string
  title: string
  description: string
  requirement_type: RequirementType
  status: string
  priority: string
  source: RequirementSource
  project_id: string
  assignee_id: string
  assignee_name?: string
  reporter_id: string
  reporter_name?: string
  acceptance_criteria: string
  business_value: string
  estimated_effort?: number
  actual_effort?: number
  progress?: number
  start_date?: string
  due_date?: string
  tags: string[]
  watchers: string[]
  participants?: string[]
  product_owner_id?: string
  acceptance_owner_id?: string
  test_owner_id?: string
  dev_owner_id?: string
  versions: RequirementResponse['versions']
  dependencies: RequirementResponse['dependencies']
  attachments: RequirementResponse['attachments']
  created_at?: string
  updated_at?: string
  approved_at?: string
  implemented_at?: string
  children_count?: number
  related_tasks_count?: number
  completed_tasks_count?: number
  parent_id?: string | null
  parent_name?: string
}

interface Props {
  visible: boolean
  requirement?: RequirementResponse | null
  projects: ProjectOption[]
  users: User[]
  statusOptions: StatusOption[]
  priorityOptions: BasicOption[]
  commonTags?: string[]
  currentUserId?: string
  versionOptions?: VersionOption[]
}

interface Emits {
  (e: 'update:visible', value: boolean): void
  (e: 'updated', requirementId: string): void
  (e: 'deleted', requirementId: string): void
  (e: 'comment-added'): void
  (e: 'request-version-options'): void
  (e: 'create-child', parentId: string): void
  (e: 'view-child', childId: string): void
}

const props = withDefaults(defineProps<Props>(), {
  requirement: null,
  commonTags: () => [],
  versionOptions: () => []
})
const emit = defineEmits<Emits>()

const activeTab = ref('activities') // 默认显示动态页签
const contentTab = ref('description')
const createTaskDialogVisible = ref(false)

// 编辑状态
const editingDescription = ref(false)
const editingAcceptance = ref(false)
const editingBusiness = ref(false)

const { formattedTypeOptions, formattedSourceOptions } = useRequirementOptions()
const requirementsStore = useRequirementsStore()
const typeOptions = formattedTypeOptions
const sourceOptions = formattedSourceOptions

// 本地用户列表（项目成员）
const localUsers = ref<User[]>([])

// 计算可用的用户列表（优先使用本地项目成员，如果没有则使用props.users作为后备）
const availableUsers = computed(() => {
  // 如果已选择项目且有项目成员，使用项目成员
  if (localRequirement.project_id && localUsers.value.length > 0) {
    return localUsers.value
  }
  // 否则返回空数组（项目必先选）
  return []
})

const localRequirement = reactive<LocalRequirement>({
  id: '',
  title: '',
  description: '',
  requirement_type: RequirementType.FUNCTIONAL,
  status: '',
  priority: RequirementPriority.MEDIUM,
  source: (sourceOptions.value[0]?.value as RequirementSource) || 'internal' as RequirementSource,
  project_id: '',
  assignee_id: '',
  reporter_id: '',
  acceptance_criteria: '',
  business_value: '',
  estimated_effort: undefined,
  actual_effort: undefined,
  start_date: undefined,
  due_date: undefined,
  tags: [],
  watchers: [],
  versions: [],
  dependencies: [],
  attachments: [],
  created_at: undefined,
  updated_at: undefined,
  approved_at: undefined,
  implemented_at: undefined,
  children_count: 0,
  related_tasks_count: 0,
  completed_tasks_count: 0,
  parent_id: undefined,
  parent_name: undefined
})

const versionSelection = ref<string[]>([])
const versionsUpdating = ref(false)
let suppressVersionWatcher = false

const drafts = reactive({
  title: '',
  description: '',
  acceptance_criteria: '',
  business_value: ''
})

const saving = reactive({
  title: false,
  description: false,
  acceptance: false,
  business: false
})

const savingFields = reactive<Record<string, boolean>>({})

// 删除状态
const deleting = ref(false)

// 字段错误信息
const fieldErrors = reactive<Record<string, string>>({})

// 字段引用
const titleFieldRef = ref<HTMLElement | null>(null)
const statusFieldRef = ref<HTMLElement | null>(null)
const projectIdFieldRef = ref<HTMLElement | null>(null)
const reporterIdFieldRef = ref<HTMLElement | null>(null)

const commonTagOptions = computed(() => {
  const tags = new Set<string>(props.commonTags || [])
  localRequirement.tags.forEach(tag => tags.add(tag))
  return Array.from(tags)
})

const selectableVersionOptions = computed<VersionOption[]>(() => {
  const map = new Map<string, VersionOption>()
  // 从 props.versionOptions 中获取版本选项
  ;(props.versionOptions || []).forEach(option => {
    const normalized = normalizeVersionOption(option)
    if (normalized.id) {
      map.set(normalized.id, normalized)
    }
  })
  // 从当前需求的版本列表中获取版本选项（用于已关联的版本）
  const currentVersions = Array.isArray(localRequirement.versions) ? localRequirement.versions : []
  currentVersions.forEach(version => {
    const normalized = normalizeVersionOption(version)
    if (normalized.id && !map.has(normalized.id)) {
      map.set(normalized.id, normalized)
    }
  })
  return Array.from(map.values())
})

const availableVersionOptions = computed<VersionOption[]>(() => {
  const projectId = localRequirement.project_id
  if (!projectId) {
    // 如果没有选择项目，返回空数组（项目必先选）
    return []
  }
  const selectedIds = new Set(versionSelection.value)
  return selectableVersionOptions.value.filter(option => {
    // 如果已选中的版本，保留（即使项目ID不匹配，也允许保留已选中的）
    if (selectedIds.has(option.id)) {
      return true
    }
    // 只显示属于当前项目的版本（必须有项目ID且匹配）
    return option.project_id === projectId
  })
})

// 从状态管理获取允许未分配的状态集合
const { requirementStates } = useRequirementStates()
const UNASSIGNED_ALLOWED_STATUS_SET = computed(() => {
  // 根据状态配置判断哪些状态允许未分配
  // 通常草稿、新建、待分配等状态允许未分配
  // 从状态配置中获取，如果状态名称包含"草稿"、"新建"、"待分配"等关键词，则认为允许未分配
  const allowedCodes = new Set<string>()
  requirementStates.value.forEach(state => {
    const name = state.name.toLowerCase()
    if (name.includes('草稿') || name.includes('新建') || name.includes('待分配') || 
        state.code === 'draft' || state.code === 'new' || state.code === 'open') {
      allowedCodes.add(state.code)
    }
  })
  // 如果没有找到匹配的状态，使用默认的后备方案
  if (allowedCodes.size === 0) {
    return new Set(['draft', 'new', 'open'])
  }
  return allowedCodes
})

const normalizeStatusCode = (status: string | null | undefined) => (status ? status.toLowerCase() : '')

const statusAllowsUnassigned = (status: string | null | undefined) => {
  const code = normalizeStatusCode(status)
  if (!code) return true
  return UNASSIGNED_ALLOWED_STATUS_SET.value.has(code)
}

const statusRequiresAssignee = (status: string | null | undefined) => !statusAllowsUnassigned(status)


const hasAssociations = computed(() => {
  const versionCount = localRequirement.versions?.length ?? 0
  const dependencyCount = localRequirement.dependencies?.length ?? 0
  return versionCount > 0 || dependencyCount > 0
})

const hasEffort = computed(() => {
  return Boolean(
    (localRequirement.estimated_effort ?? 0) ||
      (localRequirement.actual_effort ?? 0) ||
      localRequirement.start_date ||
      localRequirement.due_date
  )
})

const hasWatchers = computed(() => (localRequirement.watchers?.length ?? 0) > 0)

const canSaveDescription = computed(() => {
  if (!editingDescription.value) return false
  return drafts.description !== (localRequirement.description || '')
})
const canSaveAcceptance = computed(() => {
  if (!editingAcceptance.value) return false
  return drafts.acceptance_criteria !== (localRequirement.acceptance_criteria || '')
})
const canSaveBusiness = computed(() => {
  if (!editingBusiness.value) return false
  return drafts.business_value !== (localRequirement.business_value || '')
})

watch(
  () => props.requirement,
  (value) => {
    if (value && value.id) {
      initializeLocalRequirement(value)
      // 重置编辑状态
      editingDescription.value = false
      editingAcceptance.value = false
      editingBusiness.value = false
    }
  },
  { immediate: true }
)

watch(
  () => props.visible,
  (value) => {
    if (value && props.requirement?.id) {
      activeTab.value = 'activities'
      // 只在 requirement 变化时才重新初始化，避免重复初始化
      if (!localRequirement.id || localRequirement.id !== props.requirement.id) {
        initializeLocalRequirement(props.requirement)
      }
    }
  }
)

watch(
  () => props.versionOptions,
  () => {
    if (versionSelection.value.length > 0) {
      applyVersionSelection([...versionSelection.value])
    }
  },
  { deep: true }
)

watch(
  () => [...versionSelection.value],
  (newIds, oldIds) => {
    if (suppressVersionWatcher) return
    handleVersionSelectionChange(newIds, oldIds || [])
  }
)

watch(
  () => localRequirement.project_id,
  (projectId) => {
    if (suppressVersionWatcher) return
    if (!projectId) return
    const currentIds = versionSelection.value
    if (!currentIds.length) return
    const validIds = currentIds.filter(id => {
      const info = findVersionInfo(id, Array.isArray(localRequirement.versions) ? localRequirement.versions : [])
      if (!info.project_id) return true
      return info.project_id === projectId
    })
    const hasChanged =
      validIds.length !== currentIds.length ||
      validIds.some((id, index) => id !== currentIds[index])
    if (!hasChanged) {
      return
    }
    suppressVersionWatcher = true
    versionSelection.value = validIds
    applyVersionSelection(validIds)
    nextTick(() => {
      suppressVersionWatcher = false
    })
  }
)

async function initializeLocalRequirement(requirement: RequirementResponse | null) {
  if (requirement && requirement.id) {
    assignRequirement(requirement)
    syncDrafts()
    // 清除错误信息
    Object.keys(fieldErrors).forEach(key => delete fieldErrors[key])
    // 加载项目成员
    if (requirement.project_id) {
      try {
        localUsers.value = await requirementsStore.loadUsersForProject(requirement.project_id)
      } catch (error) {
        console.error('加载项目成员失败:', error)
        localUsers.value = []
      }
    } else {
      localUsers.value = []
    }
  }
}

function assignRequirement(requirement: RequirementResponse) {
  Object.assign(localRequirement, {
    id: requirement.id,
    title: requirement.title || '',
    description: requirement.description || '',
    requirement_type: requirement.requirement_type,
    status: requirement.status,
    priority: requirement.priority,
    source: requirement.source,
    project_id: requirement.project_id || '',
    assignee_id: requirement.assignee_id || '',
    assignee_name: requirement.assignee_name,
    reporter_id: requirement.reporter_id || '',
    reporter_name: requirement.reporter_name,
    acceptance_criteria: requirement.acceptance_criteria || '',
    business_value: requirement.business_value || '',
    estimated_effort: requirement.estimated_effort,
    actual_effort: requirement.actual_effort,
    progress: requirement.progress,
    start_date: requirement.start_date || '',
    due_date: requirement.due_date || '',
    tags: Array.isArray(requirement.tags) ? [...requirement.tags] : [],
    watchers: requirement.watchers || [],
    versions: requirement.versions || [],
    dependencies: requirement.dependencies || [],
    attachments: requirement.attachments || [],
    created_at: requirement.created_at,
    updated_at: requirement.updated_at,
    approved_at: requirement.approved_at,
    implemented_at: requirement.implemented_at,
    children_count: requirement.children_count,
    related_tasks_count: requirement.related_tasks_count,
    completed_tasks_count: requirement.completed_tasks_count,
    parent_id: requirement.parent_id,
    parent_name: requirement.parent_name || undefined
  })
  syncVersionSelectionFromLocalRequirement()
  
  // 如果有父需求ID但没有父需求名称，加载父需求信息
  if (requirement.parent_id && !requirement.parent_name) {
    loadParentRequirement(requirement.parent_id)
  }
}

// 加载父需求信息
async function loadParentRequirement(parentId: string) {
  try {
    const response = await getRequirementById(parentId)
    if (response.success && response.data) {
      localRequirement.parent_name = response.data.title
    }
  } catch (error) {
    console.error('加载父需求信息失败:', error)
  }
}

function syncDrafts() {
  drafts.title = localRequirement.title || ''
  drafts.description = localRequirement.description || ''
  drafts.acceptance_criteria = localRequirement.acceptance_criteria || ''
  drafts.business_value = localRequirement.business_value || ''
}

function sanitizeVersionIds(ids: string[]): string[] {
  return Array.from(
    new Set(
      (ids || [])
        .map(id => (id ?? '').toString().trim())
        .filter((id): id is string => Boolean(id))
    )
  )
}

function normalizeVersionOption(option: any): VersionOption {
  if (!option) {
    return { id: '', name: '' }
  }
  if (typeof option === 'string') {
    const id = option.trim()
    return {
      id,
      name: id ? `版本 ${id}` : ''
    }
  }

  const id = (option.id || option.version_id || '').toString()
  const fallbackName = id ? `版本 ${id}` : ''
  const versionNumber = option.version_number || option.versionNumber
  const name = option.name || versionNumber || fallbackName

  return {
    id,
    name,
    version_number: versionNumber || (name !== fallbackName ? name : undefined),
    status: option.status,
    project_id: option.project_id || option.projectId,
    projectName: option.projectName || option.project_name
  }
}

function findVersionInfo(id: string, existingList: any[]): VersionOption {
  const fromProps = (props.versionOptions || []).find(option => option?.id === id)
  if (fromProps) {
    return normalizeVersionOption(fromProps)
  }
  const existing = existingList.find((item: any) => {
    if (typeof item === 'string') {
      return item === id
    }
    return item?.id === id
  })
  if (existing) {
    return normalizeVersionOption(existing)
  }
  return normalizeVersionOption({ id })
}

function applyVersionSelection(ids: string[]) {
  const uniqueIds = sanitizeVersionIds(ids)
  const existingList = Array.isArray(localRequirement.versions) ? [...localRequirement.versions] : []
  const normalized = uniqueIds
    .map(id => findVersionInfo(id, existingList))
    .filter(option => Boolean(option.id))
  localRequirement.versions = normalized as RequirementResponse['versions']
}

function syncVersionSelectionFromLocalRequirement() {
  const ids = Array.isArray(localRequirement.versions)
    ? localRequirement.versions
        .map(version => (typeof version === 'string' ? version : version?.id || ''))
        .filter((id): id is string => Boolean(id))
    : []
  suppressVersionWatcher = true
  versionSelection.value = ids
  applyVersionSelection(ids)
  nextTick(() => {
    suppressVersionWatcher = false
  })
}

function handleVersionSelectVisibleChange(visible: boolean) {
  if (visible) {
    emit('request-version-options')
  }
}

async function handleVersionSelectionChange(newIdsRaw: string[], oldIdsRaw: string[]) {
  const newIds = sanitizeVersionIds(newIdsRaw)
  const oldIds = sanitizeVersionIds(oldIdsRaw || [])
  const addedIds = newIds.filter(id => !oldIds.includes(id))

  if (addedIds.length) {
    const existingList = Array.isArray(localRequirement.versions) ? localRequirement.versions : []
    const addedInfos = addedIds
      .map(id => findVersionInfo(id, existingList))
      .filter(info => info.id)

    if (localRequirement.project_id) {
      const conflict = addedInfos.find(info => info.project_id && info.project_id !== localRequirement.project_id)
      if (conflict) {
        suppressVersionWatcher = true
        versionSelection.value = oldIds
        applyVersionSelection(oldIds)
        nextTick(() => {
          suppressVersionWatcher = false
        })
        ElMessage.warning('请选择与需求所属项目一致的版本')
        return
      }
    } else {
      const derivedProjectId = addedInfos.find(info => info.project_id)?.project_id
      if (derivedProjectId) {
        localRequirement.project_id = derivedProjectId
      }
    }
  }

  if (newIds.length !== newIdsRaw.length) {
    suppressVersionWatcher = true
    versionSelection.value = newIds
    nextTick(() => {
      suppressVersionWatcher = false
    })
  }

  applyVersionSelection(newIds)
  await updateRequirementVersionAssociations(newIds, oldIds)
}

async function updateRequirementVersionAssociations(newIds: string[], oldIds: string[]) {
  const oldSet = new Set(oldIds)
  const newSet = new Set(newIds)
  const toAdd = newIds.filter(id => !oldSet.has(id))
  const toRemove = oldIds.filter(id => !newSet.has(id))

  if (!toAdd.length && !toRemove.length) {
    return
  }

  versionsUpdating.value = true
  const errors: string[] = []
  const warnings: string[] = []
  
  try {
    // 添加版本关联
    for (const versionId of toAdd) {
      try {
        await addRequirementRelation(versionId, localRequirement.id)
      } catch (error: any) {
        const message = ResponseParser.extractMessage(error) || '关联版本失败'
        // 如果版本已关联，记录为警告，继续处理其他版本
        if (message.includes('already associated') || 
            message.includes('已经关联') ||
            message.includes('已关联') ||
            message.includes('无需重复关联')) {
          warnings.push('该版本已经关联到此需求，无需重复关联')
        } else {
          // 其他错误（如项目不匹配），记录为错误并停止处理
          errors.push(message)
          throw error
        }
      }
    }
    
    // 移除版本关联
    for (const versionId of toRemove) {
      await removeRequirementRelation(versionId, localRequirement.id)
    }
    
    // 显示结果消息
    if (warnings.length > 0 && errors.length === 0) {
      // 只有警告，没有错误
      if (toAdd.length === warnings.length) {
        // 所有要添加的版本都已关联
        ElMessage.warning(warnings[0])
        suppressVersionWatcher = true
        versionSelection.value = oldIds
        applyVersionSelection(oldIds)
        nextTick(() => {
          suppressVersionWatcher = false
        })
      } else {
        // 部分版本已关联，但其他版本成功关联
        ElMessage.warning(`部分版本已关联，其他版本关联成功`)
        emit('updated', localRequirement.id)
      }
    } else if (errors.length === 0) {
      // 没有错误和警告，全部成功
      emit('updated', localRequirement.id)
      ElMessage.success('版本关联已更新')
    }
  } catch (error) {
    let message = ResponseParser.extractMessage(error) || '更新版本关联失败'
    // 处理后端返回的项目不匹配错误
    if (message.includes('Requirement must belong to the same project as the version') || 
        message.includes('需求必须属于与版本相同的项目')) {
      message = '无法关联版本：需求必须属于与版本相同的项目。请选择与需求所属项目一致的版本。'
    }
    // 恢复选择
    suppressVersionWatcher = true
    versionSelection.value = oldIds
    applyVersionSelection(oldIds)
    nextTick(() => {
      suppressVersionWatcher = false
    })
    ElMessage.error(message)
  } finally {
    versionsUpdating.value = false
  }
}

async function addRequirementRelation(versionId: string, requirementId: string) {
  // 先验证版本的项目ID是否与需求的项目ID匹配
  if (localRequirement.project_id) {
    try {
      const versionResponse = await versionAPI.getVersionById(versionId)
      const versionParsed = ResponseParser.parseResponse(versionResponse)
      if (versionParsed.success && versionParsed.data) {
        const versionData = versionParsed.data as any
        const versionProjectId = versionData?.project_id
        if (versionProjectId && versionProjectId !== localRequirement.project_id) {
          throw new Error(`版本必须属于与需求相同的项目。需求属于项目 ${localRequirement.project_id}，版本属于项目 ${versionProjectId}`)
        }
      }
    } catch (error: any) {
      // 如果获取版本详情失败，检查错误消息是否已经是我们想要的消息
      if (error.message && error.message.includes('版本必须属于')) {
        throw error
      }
      // 否则继续尝试关联，让后端验证
      console.warn('获取版本详情失败，继续尝试关联:', error)
    }
  }
  
  const response = await versionAPI.addRequirementToVersion(versionId, {
    requirement_id: requirementId,
    relation_type: RelationType.INCLUDED
  })
  const parsed = ResponseParser.parseResponse(response)
  if (!parsed.success) {
    let errorMessage = parsed.message || '关联版本失败'
    // 处理版本已关联的错误
    if (errorMessage.includes('already associated') || 
        errorMessage.includes('已经关联') ||
        errorMessage.includes('已关联')) {
      errorMessage = '该版本已经关联到此需求，无需重复关联'
    }
    throw new Error(errorMessage)
  }
}

async function removeRequirementRelation(versionId: string, requirementId: string) {
  const response = await versionAPI.removeRequirementFromVersion(versionId, requirementId)
  const parsed = ResponseParser.parseResponse(response)
  if (!parsed.success) {
    throw new Error(parsed.message || '移除版本关联失败')
  }
}

// 使用共享工具函数的包装函数
const clearFieldErrorWrapper = (field: string) => clearFieldError(field, fieldErrors)
const validateRequiredFieldWrapper = (field: string, value: any): boolean => {
  return validateRequiredField(field, value, fieldErrors, {
    titleFieldRef,
    statusFieldRef,
    projectIdFieldRef,
    reporterIdFieldRef
  })
}

async function saveTitle() {
  const value = drafts.title.trim()
  if (!validateRequiredFieldWrapper('title', value)) {
    ElMessage.warning('请完善必填字段')
    return
  }
  await persistField({ title: value }, 'title')
}

// 编辑状态管理函数
function startEditDescription() {
  editingDescription.value = true
}

function cancelEditDescription() {
  editingDescription.value = false
  // 恢复原始值
  drafts.description = localRequirement.description || ''
}

function startEditAcceptance() {
  editingAcceptance.value = true
}

function cancelEditAcceptance() {
  editingAcceptance.value = false
  // 恢复原始值
  drafts.acceptance_criteria = localRequirement.acceptance_criteria || ''
}

function startEditBusiness() {
  editingBusiness.value = true
}

function cancelEditBusiness() {
  editingBusiness.value = false
  // 恢复原始值
  drafts.business_value = localRequirement.business_value || ''
}

async function saveDescription() {
  const MAX_DESCRIPTION_LENGTH = 100000
  const description = drafts.description || ''
  
  if (description.length > MAX_DESCRIPTION_LENGTH) {
    ElMessage.warning(`需求描述内容过长（${description.length} 字符），最多支持 ${MAX_DESCRIPTION_LENGTH} 字符，请精简内容后重试`)
    return
  }
  
  await persistField({ description }, 'description')
  editingDescription.value = false
}

async function saveAcceptance() {
  const MAX_ACCEPTANCE_LENGTH = 5000
  const acceptance_criteria = drafts.acceptance_criteria || ''
  
  if (acceptance_criteria.length > MAX_ACCEPTANCE_LENGTH) {
    ElMessage.warning(`验收标准内容过长（${acceptance_criteria.length} 字符），最多支持 ${MAX_ACCEPTANCE_LENGTH} 字符，请精简内容后重试`)
    return
  }
  
  await persistField({ acceptance_criteria }, 'acceptance')
  editingAcceptance.value = false
}

async function saveBusiness() {
  const MAX_BUSINESS_LENGTH = 2000
  const business_value = drafts.business_value || ''
  
  if (business_value.length > MAX_BUSINESS_LENGTH) {
    ElMessage.warning(`商业价值内容过长（${business_value.length} 字符），最多支持 ${MAX_BUSINESS_LENGTH} 字符，请精简内容后重试`)
    return
  }
  
  await persistField({ business_value }, 'business')
  editingBusiness.value = false
}

async function persistField(payload: RequirementUpdate, section: keyof typeof saving) {
  if (!localRequirement.id) {
    throw new Error('需求ID不存在')
  }

  saving[section] = true
  try {
    const response = await updateRequirement(localRequirement.id, payload)
    const parsed = ResponseParser.parseResponse(response)
    if (!parsed.success) {
      throw new Error(parsed.message || '保存失败')
    }
    Object.assign(localRequirement, payload)
    syncDrafts()
    emit('updated', localRequirement.id)
    ElMessage.success('保存成功')
  } catch (error) {
    const message = ResponseParser.extractMessage(error) || '保存失败'
    ElMessage.error(message)
  } finally {
    saving[section] = false
  }
}

async function updateSimpleField(field: keyof RequirementUpdate, value: any) {
  const previous = (localRequirement as any)[field]
  let nextValue = value

  // 验证必填字段（在更新本地状态之前验证）
  if (field === 'title' || field === 'project_id' || field === 'reporter_id' || field === 'status') {
    // 对于必填字段，如果值为空，先验证
    if (value === '' || value === null || value === undefined || (typeof value === 'string' && !value.trim())) {
      if (!validateRequiredFieldWrapper(field, value)) {
        ElMessage.warning('请完善必填字段')
        return
      }
    } else {
      // 如果值不为空，清除可能的错误信息
      clearFieldErrorWrapper(field)
    }
  }

  // 处理空值
  if (value === '' || value === undefined) {
    if (field === 'start_date' || field === 'due_date' || field === 'estimated_effort') {
      nextValue = null
    } else if (field === 'assignee_id' || field === 'reporter_id') {
      nextValue = null
    } else if (field === 'tags') {
      nextValue = []
    } else {
      nextValue = value
    }
  }

  // 字段特定验证和处理
  if (field === 'assignee_id') {
    const normalized = typeof value === 'string' ? value.trim() : (value || null)
    if (!normalized && statusRequiresAssignee(localRequirement.status)) {
      ElMessage.warning('该状态下必须指定负责人')
      return
    }
    nextValue = normalized
  } else if (field === 'status') {
    const normalizedStatus = typeof value === 'string' ? value : ''
    const hasAssignee = Boolean(localRequirement.assignee_id && localRequirement.assignee_id.toString().trim())
    if (statusRequiresAssignee(normalizedStatus) && !hasAssignee) {
      ElMessage.warning('该状态下必须指定负责人')
      return
    }
    nextValue = normalizedStatus
  } else if (field === 'project_id') {
    // 项目ID处理：确保是字符串且不为空
    nextValue = typeof value === 'string' && value.trim() ? value.trim() : (value || null)
    // 如果项目改变，需要检查版本关联并加载项目成员
    if (nextValue !== previous) {
      // 加载新项目的成员
      if (nextValue) {
        try {
          localUsers.value = await requirementsStore.loadUsersForProject(nextValue)
          // 如果当前选择的报告人或负责人不在新项目的成员列表中，清空选择
          if (localRequirement.reporter_id && !localUsers.value.find(u => u.id === localRequirement.reporter_id)) {
            // 不清空，保留原值，但会在保存时验证
          }
          if (localRequirement.assignee_id && !localUsers.value.find(u => u.id === localRequirement.assignee_id)) {
            // 不清空，保留原值，但会在保存时验证
          }
        } catch (error) {
          console.error('加载项目成员失败:', error)
          localUsers.value = []
        }
      } else {
        localUsers.value = []
      }
      
      // 检查并清空不属于新项目的版本选择
      if (nextValue && versionSelection.value.length > 0) {
        // 从 props.versionOptions 中获取属于新项目的版本ID列表
        const validVersionIds = (props.versionOptions || [])
          .filter(option => option.project_id === nextValue)
          .map(option => option.id)
        
        // 过滤出属于新项目的版本
        const validSelectedVersions = versionSelection.value.filter(id => validVersionIds.includes(id))
        
        if (validSelectedVersions.length !== versionSelection.value.length) {
          const removedCount = versionSelection.value.length - validSelectedVersions.length
          suppressVersionWatcher = true
          versionSelection.value = validSelectedVersions
          nextTick(() => {
            suppressVersionWatcher = false
          })
          if (removedCount > 0) {
            ElMessage.warning(`已移除 ${removedCount} 个不属于新项目的版本关联`)
          }
        }
      } else if (!nextValue) {
        // 如果没有选择项目，清空所有版本选择
        if (versionSelection.value.length > 0) {
          suppressVersionWatcher = true
          versionSelection.value = []
          nextTick(() => {
            suppressVersionWatcher = false
          })
        }
      }
    }
  } else if (field === 'reporter_id') {
    nextValue = typeof value === 'string' ? value.trim() : (value || null)
  } else if (field === 'start_date' || field === 'due_date') {
    nextValue = value || null
  } else if (field === 'estimated_effort') {
    nextValue = value !== null && value !== undefined ? Number(value) : null
  } else if (field === 'tags') {
    nextValue = Array.isArray(value) ? value : []
  }

  // 比较值是否变化（处理 null/undefined/空字符串的等价性）
  const isEqual = (a: any, b: any) => {
    if (a === b) return true
    if ((a === null || a === undefined || a === '') && (b === null || b === undefined || b === '')) return true
    if (Array.isArray(a) && Array.isArray(b)) {
      if (a.length !== b.length) return false
      return a.every((val, idx) => val === b[idx])
    }
    return false
  }

  if (isEqual(nextValue, previous)) {
    return
  }

  // 更新本地状态
  ;(localRequirement as any)[field] = nextValue

  if (!localRequirement.id) {
    throw new Error('需求ID不存在')
  }

  // 防止重复提交
  if (savingFields[field as string]) {
    return
  }

  savingFields[field as string] = true
  try {
    // 构建请求载荷
    let payloadValue = nextValue
    
    // 特殊处理：空字符串转为 null
    if (payloadValue === '') {
      if (field === 'assignee_id' || field === 'reporter_id' || field === 'start_date' || field === 'due_date' || field === 'estimated_effort') {
        payloadValue = null
      }
    }
    
    // 特殊处理：日期字段需要转换为完整的 datetime 格式（后端期望 datetime 格式）
    if (field === 'start_date' || field === 'due_date') {
      if (payloadValue === null || payloadValue === undefined) {
        // null 值保持不变
        payloadValue = null
      } else if (typeof payloadValue === 'string') {
        // 如果已经是完整的 datetime 格式（包含 T），则直接使用
        if (payloadValue.includes('T') || payloadValue.includes(' ')) {
          // 已经是 datetime 格式，保持不变
          // 如果包含空格，替换为 T
          if (payloadValue.includes(' ')) {
            payloadValue = payloadValue.replace(' ', 'T')
          }
        } else if (payloadValue.match(/^\d{4}-\d{2}-\d{2}$/)) {
          // 日期格式（YYYY-MM-DD），转换为 datetime 格式（YYYY-MM-DDTHH:mm:ss）
          payloadValue = `${payloadValue}T00:00:00`
        } else {
          // 其他格式，尝试解析并转换
          try {
            const date = new Date(payloadValue)
            if (!isNaN(date.getTime())) {
              // 转换为 ISO 格式（YYYY-MM-DDTHH:mm:ss）
              payloadValue = date.toISOString().split('.')[0] // 移除毫秒部分
            }
          } catch (e) {
            console.warn(`无法解析日期格式: ${payloadValue}`, e)
          }
        }
      }
    }

    const response = await updateRequirement(localRequirement.id, { [field]: payloadValue })
    const parsed = ResponseParser.parseResponse(response)
    if (!parsed.success) {
      throw new Error(parsed.message || '更新失败')
    }
    
    // 更新成功后，同步本地数据（如果后端返回了更新后的数据）
    if (parsed.data) {
      const updated = parsed.data as RequirementResponse
      if (updated[field as keyof RequirementResponse] !== undefined) {
        ;(localRequirement as any)[field] = updated[field as keyof RequirementResponse]
      }
      
      // 如果更新的是项目ID，需要处理版本关联
      if (field === 'project_id' && updated.versions !== undefined) {
        localRequirement.versions = updated.versions
        syncVersionSelectionFromLocalRequirement()
      }
    }
    
    emit('updated', localRequirement.id)
    ElMessage.success('已更新')
  } catch (error) {
    // 恢复原值
    ;(localRequirement as any)[field] = previous
    const message = ResponseParser.extractMessage(error) || '更新失败'
    ElMessage.error(message)
  } finally {
    savingFields[field as string] = false
  }
}

function handleClose() {
  emit('update:visible', false)
}

// 处理删除点击
async function handleDeleteClick() {
  if (!localRequirement.id) {
    return
  }

  try {
    await ElMessageBox.confirm(
      `确定要删除需求"${localRequirement.title}"吗？此操作不可恢复。`,
      '删除确认',
      {
        confirmButtonText: '确定删除',
        cancelButtonText: '取消',
        type: 'warning',
        confirmButtonClass: 'el-button--danger',
        beforeClose: async (action, instance, done) => {
          if (action === 'confirm') {
            instance.confirmButtonLoading = true
            try {
              await performDelete()
              done()
            } catch (error) {
              instance.confirmButtonLoading = false
            }
          } else {
            done()
          }
        }
      }
    )
  } catch (error) {
    // 用户取消删除
    if (error !== 'cancel') {
      console.error('删除确认对话框错误:', error)
    }
  }
}

// 执行删除操作
async function performDelete() {
  if (!localRequirement.id) {
    return
  }

  deleting.value = true
  try {
    const response = await deleteRequirement(localRequirement.id)
    const parsed = ResponseParser.parseResponse(response)
    
    if (!parsed.success) {
      throw new Error(parsed.message || '删除失败')
    }

    ElMessage.success('删除成功')
    emit('deleted', localRequirement.id)
    emit('update:visible', false)
  } catch (error) {
    const message = ResponseParser.extractMessage(error) || '删除失败'
    ElMessage.error(message)
    throw error
  } finally {
    deleting.value = false
  }
}

function handleCommentCountChange() {
  emit('comment-added')
}

// 处理关联任务更新
function handleRelatedTaskUpdated() {
  // 重新加载需求数据以更新任务统计
  if (props.requirement?.id) {
    emit('updated', props.requirement.id)
  }
}

// 处理创建任务
function handleCreateTask() {
  createTaskDialogVisible.value = true
}

// 关联项标签页引用
const associationsTabRef = ref<{ refreshTasks: () => Promise<void>; refreshDefects: () => Promise<void> } | null>(null)

// 处理任务创建成功
function handleTaskCreated() {
  // 重新加载需求数据以更新任务统计
  if (props.requirement?.id) {
    emit('updated', props.requirement.id)
  }
  // 切换到关联任务页签（关联项标签页下的任务子标签）
  activeTab.value = 'associations'
  // 手动触发关联任务列表刷新
  nextTick(() => {
    if (associationsTabRef.value) {
      associationsTabRef.value.refreshTasks()
    }
  })
}

// 处理新建子需求
function handleCreateChild(parentId: string) {
  // 触发新建子需求事件，传递父需求ID
  emit('create-child', parentId)
}

// 处理查看子需求
function handleViewChild(childId: string) {
  // 触发查看子需求事件
  emit('view-child', childId)
}

// 处理子需求更新
function handleChildUpdated() {
  // 重新加载需求数据以更新子需求统计
  if (props.requirement?.id) {
    emit('updated', props.requirement.id)
  }
}

// 处理查看父需求
function handleViewParent(parentId: string | null | undefined) {
  if (parentId) {
    emit('view-child', parentId)
  }
}

// 使用共享工具函数的包装函数
const getStatusTypeWrapper = (status: string) => getStatusType(status, props.statusOptions)
const getStatusTextWrapper = (status: string) => getStatusText(status, props.statusOptions)
const getPriorityTypeWrapper = (priority: string) => getPriorityType(priority, props.priorityOptions)
const getPriorityTextWrapper = (priority: string) => getPriorityText(priority, props.priorityOptions)
const getTypeTextWrapper = (type: RequirementType) => getTypeText(type)

function getDependencyText(type: string) {
  const map: Record<string, string> = {
    blocks: '阻塞',
    depends_on: '依赖',
    relates_to: '关联'
  }
  return map[type] || type
}

// 格式化日期时间（完整格式：YYYY-MM-DD HH:mm:ss）
function formatDateTimeDisplay(datetime?: string) {
  if (!datetime) return '-'
  return formatDateTime(datetime, 'YYYY-MM-DD HH:mm:ss')
}

// 格式化工时（人天）
function formatEffort(effort?: number | null): string {
  if (effort === null || effort === undefined) return '0 人天'
  return `${effort} 人天`
}

function getVersionDisplayLabel(version: any) {
  if (version.version_number && version.name) {
    return `${version.version_number} - ${version.name}`
  }
  if (version.version_number) return version.version_number
  if (version.name) return version.name
  return version.id || ''
}

async function handleDownloadAttachmentWrapper(attachment: any): Promise<void> {
  if (!attachment || !attachment.url) {
    return Promise.resolve()
  }
  window.open(attachment.url, '_blank')
  return Promise.resolve()
}


async function handleUploadAttachment(file: File): Promise<RequirementAttachment> {
  if (!localRequirement.id) {
    throw new Error('需求ID不存在')
  }
  const response = await uploadRequirementAttachment(localRequirement.id, file)
  if (response.success && response.data) {
    return response.data
  }
  throw new Error(response.message || '上传失败')
}

async function handleDeleteAttachmentWrapper(attachment: any): Promise<void> {
  if (!attachment || !attachment.id) {
    throw new Error('附件ID不存在')
  }
  return handleDeleteAttachment(attachment.id)
}

async function handleDeleteAttachment(attachmentId: string): Promise<void> {
  if (!localRequirement.id) {
    throw new Error('需求ID不存在')
  }
  const response = await deleteRequirementAttachment(localRequirement.id, attachmentId)
  if (!response.success) {
    throw new Error(response.message || '删除失败')
  }
}

async function handleAttachmentMutation() {
  // 刷新需求详情以获取最新的附件列表
  if (localRequirement.id) {
    try {
      const response = await getRequirementById(localRequirement.id)
      if (response.success && response.data) {
        localRequirement.attachments = response.data.attachments || []
      }
    } catch (error) {
      console.error('刷新附件列表失败:', error)
    }
  }
}

// 处理从关联项标签页触发的需求更新（更新项目或版本）
async function handleUpdateRequirementFromAssociation(data: { project_id?: string; version_ids?: string[] }) {
  try {
    const updates: any = {}
    
    // 更新项目ID
    if (data.project_id && data.project_id !== localRequirement.project_id) {
      updates.project_id = data.project_id
    }
    
    // 更新版本关联
    if (data.version_ids) {
      // 更新需求的版本关联
      await updateRequirementVersionAssociations(data.version_ids, localRequirement.versions?.map(v => v.id) || [])
    }
    
    // 如果有其他更新，执行更新
    if (Object.keys(updates).length > 0) {
      const response = await updateRequirement(localRequirement.id, updates)
      const parsed = ResponseParser.parseResponse(response)
      if (parsed.success) {
        Object.assign(localRequirement, updates)
        syncDrafts()
        emit('updated', localRequirement.id)
        ElMessage.success('需求信息已更新')
      } else {
        throw new Error(parsed.message || '更新失败')
      }
    } else if (data.version_ids) {
      // 如果只是更新版本，上面的 updateRequirementVersionAssociations 已经处理了
      ElMessage.success('需求版本信息已更新')
    }
  } catch (error) {
    const message = ResponseParser.extractMessage(error) || '更新需求信息失败'
    ElMessage.error(message)
    throw error
  }
}

function handleRelatedDefectUpdated() {
  // 关联缺陷更新后的处理
  // 可以在这里刷新需求详情或触发其他操作
  if (localRequirement.id) {
    getRequirementById(localRequirement.id).then(response => {
      if (response.success && response.data) {
        // 可以更新相关数据
      }
    }).catch(error => {
      console.error('刷新缺陷列表失败:', error)
    })
  }
}
</script>

<style scoped lang="scss">
.requirement-detail-dialog {
  :deep(.el-dialog) {
    max-height: 90vh;
    display: flex;
    flex-direction: column;
  }

  :deep(.el-dialog__body) {
    padding: 24px;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }

  :deep(.el-dialog__header) {
    padding: 20px 24px;
    border-bottom: 1px solid #ebeef5;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  :deep(.el-dialog__title) {
    font-size: 18px;
    font-weight: 600;
    color: #303133;
  }

  :deep(.el-dialog__footer) {
    padding: 16px 24px;
    border-top: 1px solid #ebeef5;
    flex-shrink: 0;
  }
  
}

.requirement-detail {
  display: flex;
  flex-direction: column;
  gap: 24px;
  height: 100%;
  min-height: 0;
}

.detail-header {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 16px;
}

.header-top {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.detail-id {
  font-size: 13px;
  color: #909399;
  background: #f4f6fa;
  padding: 4px 10px;
  border-radius: 4px;
}

.status-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.title-section {
  margin-bottom: 8px;
}

.title-edit-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.title-input {
  flex: 1;
  min-width: 0;
}

.detail-title {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  color: #303133;
}

.header-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  font-size: 13px;
  color: #606266;
}

.header-actions {
  display: flex;
  align-items: flex-start;
}

.detail-body {
  display: flex;
  gap: 24px;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  align-items: flex-start;
}

.primary-column {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow-y: auto;
  padding-right: 8px;
  min-height: 0;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;
  }
}

.section-card {
  background: #fff;
  border: 1px solid #ebeef5;
  border-radius: 12px;
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  box-shadow: 0 4px 12px rgba(31, 56, 88, 0.05);
}

.tabs-card {
  padding: 0;
  overflow: hidden;
}

.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.section-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.section-content {
  font-size: 14px;
  color: #606266;
  line-height: 1.7;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.rich-text-content {
  padding: 24px;
  background-color: #ffffff;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  max-height: 600px;
  overflow-y: auto;
  overflow-x: hidden;
  word-wrap: break-word;
  word-break: break-word;
  font-size: 14px;
  line-height: 1.8;
  color: #303133;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;
  }

  &::-webkit-scrollbar-thumb:hover {
    background: #a8a8a8;
  }

  &::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 3px;
  }

  // 标题样式
  :deep(h1),
  :deep(h2),
  :deep(h3),
  :deep(h4),
  :deep(h5),
  :deep(h6) {
    margin: 20px 0 12px 0;
    font-weight: 600;
    color: #303133;
    line-height: 1.5;
  }

  :deep(h1) {
    font-size: 24px;
    border-bottom: 2px solid #e5e7eb;
    padding-bottom: 8px;
  }

  :deep(h2) {
    font-size: 20px;
    border-bottom: 1px solid #e5e7eb;
    padding-bottom: 6px;
  }

  :deep(h3) {
    font-size: 18px;
  }

  :deep(h4) {
    font-size: 16px;
  }

  :deep(h5) {
    font-size: 15px;
  }

  :deep(h6) {
    font-size: 14px;
  }

  // 段落样式
  :deep(p) {
    margin: 12px 0;
    line-height: 1.8;
    color: #606266;
  }

  // 列表样式
  :deep(ul),
  :deep(ol) {
    margin: 12px 0;
    padding-left: 24px;
    line-height: 1.8;
  }

  :deep(li) {
    margin: 6px 0;
    color: #606266;
  }

  :deep(ul) {
    list-style-type: disc;
  }

  :deep(ol) {
    list-style-type: decimal;
  }

  // 链接样式
  :deep(a) {
    color: #409eff;
    text-decoration: none;
    transition: color 0.2s;

    &:hover {
      color: #66b1ff;
      text-decoration: underline;
    }
  }

  // 图片样式
  :deep(img) {
    max-width: 100%;
    height: auto;
    border-radius: 6px;
    margin: 16px 0;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    display: block;
  }

  // 代码块样式
  :deep(pre) {
    background-color: #f5f7fa;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    padding: 16px;
    margin: 12px 0;
    overflow-x: auto;
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 13px;
    line-height: 1.6;
  }

  :deep(code) {
    background-color: #f5f7fa;
    padding: 2px 6px;
    border-radius: 3px;
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 13px;
    color: #e83e8c;
  }

  :deep(pre code) {
    background-color: transparent;
    padding: 0;
    color: #303133;
  }

  // 引用样式
  :deep(blockquote) {
    border-left: 4px solid #409eff;
    padding: 12px 16px;
    margin: 12px 0;
    background-color: #f0f9ff;
    border-radius: 4px;
    color: #606266;
    font-style: italic;
  }

  // 表格样式
  :deep(table) {
    width: 100%;
    border-collapse: collapse;
    margin: 16px 0;
    font-size: 14px;
  }

  :deep(th),
  :deep(td) {
    border: 1px solid #e5e7eb;
    padding: 10px 12px;
    text-align: left;
  }

  :deep(th) {
    background-color: #f5f7fa;
    font-weight: 600;
    color: #303133;
  }

  :deep(tr:nth-child(even)) {
    background-color: #fafafa;
  }

  // 分割线样式
  :deep(hr) {
    border: none;
    border-top: 1px solid #e5e7eb;
    margin: 20px 0;
  }

  // 强调样式
  :deep(strong),
  :deep(b) {
    font-weight: 600;
    color: #303133;
  }

  :deep(em),
  :deep(i) {
    font-style: italic;
  }

  // 删除线样式
  :deep(del),
  :deep(s) {
    text-decoration: line-through;
    color: #909399;
  }

  // 标记样式
  :deep(mark) {
    background-color: #fff3cd;
    padding: 2px 4px;
    border-radius: 2px;
  }

  // 空内容提示
  &:empty::before {
    content: '暂无描述';
    color: #909399;
    font-style: italic;
  }
}

.text-content {
  padding: 24px;
  background-color: #ffffff;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  white-space: pre-wrap;
  max-height: 600px;
  overflow-y: auto;
  overflow-x: hidden;
  word-wrap: break-word;
  word-break: break-word;
  font-size: 14px;
  line-height: 1.8;
  color: #606266;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;
  }

  &::-webkit-scrollbar-thumb:hover {
    background: #a8a8a8;
  }

  &::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 3px;
  }

  // 空内容提示
  &:empty::before {
    content: '暂无内容';
    color: #909399;
    font-style: italic;
  }
}

.empty-content {
  padding: 40px 0;
  color: #909399;
  font-style: italic;
  text-align: center;
}

.content-tabs {
  :deep(.el-tabs__header) {
    margin: 0;
    padding: 0 24px;
    border-bottom: 1px solid #ebeef5;
  }

  :deep(.el-tabs__content) {
    padding: 0;
  }
  
  :deep(.el-tab-pane) {
    padding: 24px;
  }
}

.tab-content-wrapper {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.detail-tabs {
  :deep(.el-tabs__header) {
    margin: 0;
    padding: 0 24px;
    border-bottom: 1px solid #ebeef5;
  }

  :deep(.el-tabs__content) {
    padding: 0;
  }
  
  :deep(.el-tab-pane) {
    padding: 24px;
  }
}

.association-sub-tabs {
  :deep(.el-tabs__header) {
    margin: 0;
  }

  :deep(.el-tabs__content) {
    padding: 0;
  }
}


.tab-content {
  min-height: 300px;
}

.other-info {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.other-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.other-title {
  font-size: 15px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid #ebeef5;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 16px;
}

.stat-card {
  border: 1px solid #ebeef5;
  border-radius: 10px;
  background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stat-label {
  font-size: 13px;
  color: #909399;
}

.stat-value {
  font-size: 24px;
  font-weight: 600;
  color: #303133;
}

.association-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
}


.association-title {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 12px;
  color: #303133;
}

.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tag-item {
  margin: 0;
}

.dependency-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: #606266;
}

.dependency-title {
  font-weight: 500;
  color: #303133;
}

.dependency-type {
  font-size: 12px;
  color: #909399;
}

.dependency-desc {
  margin: 0;
  font-size: 13px;
  color: #606266;
}

.other-info {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.other-row {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: #606266;
}

.other-label {
  color: #909399;
}

.attachments-block {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 12px;
}

.attachments-title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
}

.attachments-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.attachment-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  background: #fafafa;
}

.attachment-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
}

.attachment-name {
  color: #303133;
}

.attachment-meta {
  color: #909399;
}

.side-column {
  width: 400px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: 24px;
  position: sticky;
  top: 0;
  align-self: flex-start;
  gap: 16px;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;
  }
}

.info-card {
  background: #fff;
  border: 1px solid #ebeef5;
  border-radius: 12px;
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  box-shadow: 0 4px 12px rgba(31, 56, 88, 0.05);
}

.info-card-title {
  font-size: 15px;
  font-weight: 600;
  color: #303133;
}

.info-form-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.info-item {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: #606266;
  gap: 12px;
}

.align-start {
  align-items: flex-start;
}

.info-label {
  color: #909399;
}

.required {
  color: #f56c6c;
  margin-left: 4px;
}

.field-label {
  font-size: 14px;
  color: #606266;
  margin-bottom: 8px;
  font-weight: 500;
}

.field-error {
  :deep(.el-input__wrapper) {
    border-color: #f56c6c !important;
    box-shadow: 0 0 0 1px #f56c6c inset !important;
  }
  
  :deep(.el-select__wrapper) {
    border-color: #f56c6c !important;
    box-shadow: 0 0 0 1px #f56c6c inset !important;
  }
}

.error-message {
  color: #f56c6c;
  font-size: 12px;
  margin-top: 4px;
  line-height: 1.5;
}

.info-value {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
  text-align: right;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.association-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

@media (max-width: 992px) {
  .detail-body {
    flex-direction: column;
    max-height: none;
  }

  .side-column {
    width: 100%;
    border-left: none;
    border-top: 1px solid #ebeef5;
    padding-left: 0;
    padding-top: 16px;
  }
}

.dialog-header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
}
</style>